import { CurOrgId } from '../../decorators/current-org.decorator';
import { FindOptionsWhere, In, Like } from 'typeorm';
import { Product, productStatustype } from './models/product.entity';
import { Result } from '../../dto/result.type';
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
import { UseGuards } from '@nestjs/common';
import { GqlAuthGuard } from '../../guards/auth.guard';
import { ProductResult, ProductResults } from './dto/result-product.output';
import { PartialProductInput } from './dto/product.input';
import { ProductType } from './dto/product.type';
import { ProductService } from './product.service';
import { CurUserId } from '../../decorators/current-user.decorator';
import { PageInput } from '../../dto/page.input';
import { CardRecordService } from '../cardRecord/cardRecord.service';

@Resolver(() => ProductType)
@UseGuards(GqlAuthGuard)
export class ProductResolver {
  constructor(
    private readonly productService: ProductService,
    private readonly cardRecordService: CardRecordService,
  ) {}

  @Query(() => ProductResult)
  async getProductInfo(
    @Args('id') id: string,
  ): Promise<{ data?: Product; message: string }> {
    const result = await this.productService.findById(id);
    if (result) {
      return {
        data: result,
        message: '获取成功',
      };
    }
    return {
      message: '商品信息不存在',
    };
  }

  @Mutation(() => ProductResult)
  async commitProductInfo(
    @Args('params') params: PartialProductInput,
    @CurUserId() userId: string,
    @CurOrgId() orgId: string,
    @Args('id', { nullable: true }) id: string,
  ): Promise<Result> {
    if (!id) {
      const res = await this.productService.create({
        ...params,
        orgId: orgId,
        createdBy: userId,
        status: productStatustype.UN_PUTAWAY,
      });
      return {
        message: res ? '创建成功' : '创建失败',
      };
    }
    const product = await this.productService.findById(id);
    if (product) {
      const res = await this.productService.updateById(id, {
        ...params,
        updatedBy: userId,
      });
      return {
        message: res ? '更新成功' : '更新失败',
      };
    }
    return {
      message: '商品信息不存在',
    };
  }

  @Query(() => ProductResults)
  async getProducts(
    @CurUserId() userId: string,
    @Args('page') page: PageInput,
    @CurOrgId() orgId: string,
    @Args('name', { nullable: true }) name?: string,
  ): Promise<ProductResults> {
    const { pageNum, pageSize } = page;
    const where: FindOptionsWhere<Product> = {
      createdBy: userId,
      orgId,
    };
    if (name) {
      where.name = Like(`%${name}%`);
    }
    const [results, total] = await this.productService.findproducts({
      start: pageNum === 1 ? 0 : (pageNum - 1) * pageSize,
      length: pageSize,
      where,
    });
    return {
      data: results,
      page: {
        pageNum,
        pageSize,
        total,
      },
      message: '获取成功',
    };
  }

  @Mutation(() => Result)
  async deleteProduct(
    @Args('id') id: string,
    @CurUserId() userId: string,
  ): Promise<Result> {
    const result = await this.productService.findById(id);
    if (result) {
      const delRes = await this.productService.deleteById(id, userId);
      if (delRes) {
        return {
          message: '删除成功',
        };
      }
      return {
        message: '删除失败',
      };
    }
    return {
      message: '商品信息不存在',
    };
  }

  @Query(() => ProductResults)
  async getProductsByType(
    @Args('page') page: PageInput,
    @Args('type', { nullable: true }) type?: string,
    @Args('name', { nullable: true }) name?: string,
  ): Promise<ProductResults> {
    const { pageNum, pageSize } = page;
    const where: FindOptionsWhere<Product> = {
      status: productStatustype.PUTAWAY,
    };
    if (name) {
      where.name = Like(`%${name}%`);
    }
    if (type) {
      where.type = type;
    }
    const [results, total] = await this.productService.findproducts({
      start: pageNum === 1 ? 0 : (pageNum - 1) * pageSize,
      length: pageSize,
      where,
    });
    return {
      data: results,
      page: {
        pageNum,
        pageSize,
        total,
      },
      message: '获取成功',
    };
  }

  @Query(() => ProductResults)
  async getRecommendProducts(
    @Args('orgId', { nullable: true }) orgId?: string,
  ): Promise<ProductResults> {
    const where: FindOptionsWhere<Product> = {
      orgId,
    };
    const [results, total] = await this.productService.findproducts({
      start: 0,
      length: 0,
      where,
    });
    let resNum = Math.floor(Math.random() * (total + 1));
    if (resNum > 5) resNum = 5;
    const res = results.slice(0, resNum);
    return {
      data: res,
      message: '获取成功',
    };
  }

  // 通过机构id，用户id 查询购买过的商品
  @Query(() => ProductResults)
  async getProductsByOrgAndUser(
    @Args('userId') userId?: string,
    @Args('orgId') orgId?: string,
  ): Promise<ProductResults> {
    // 获取消费卡记录即可查询到购买过的商品
    const [cardRecordResults] = await this.cardRecordService.findCardRecords({
      start: 0,
      length: 9999,
      where: {
        studentId: userId,
        orgId,
      },
    });
    const products = [
      ...new Set(cardRecordResults.map((item) => item.productId)),
    ];
    const where: FindOptionsWhere<Product> = {};
    where.id = In(products);
    const [results] = await this.productService.findproducts({
      start: 0,
      length: 9999,
      where,
    });
    return {
      data: results,
      message: '获取成功',
    };
  }
}
